home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #2 / Ham Radio 2000 - Volume 2.iso / HAMV2 / TCP_IP / TNOS230S / REQSVR.C < prev    next >
C/C++ Source or Header  |  1997-08-18  |  18KB  |  678 lines

  1. /* Those who hate GOTOs (like me) B E W A R E............
  2.    To save code space, extensive use of GOTOs was used to prevent
  3.    repetition of code. Could SURELY be cleaner, but it works!
  4.    KO4KS    */
  5.  
  6. #include "global.h"
  7. #include "ctype.h"
  8. #include "commands.h"
  9. #include "bm.h"
  10. #ifdef MSDOS
  11. #undef FA_DIREC
  12. #define FA_DIREC 0x10
  13. #else
  14. #include "dirutil.h"
  15. #endif
  16. #include "ftpserv.h"
  17.  
  18. #if !defined(_lint)
  19. static char rcsid[] OPTIONAL = "$Id: reqsvr.c,v 1.26 1997/08/19 01:19:22 root Exp root $";
  20. #endif
  21.  
  22. extern int mailuser (FILE *data,const char *from,const char *to,const char *origto);
  23. extern int groupcommand (char *action,char *group,char *user,int local, FILE **out, FILE *in);
  24. extern char *Mbfwdinfo;
  25. extern char shortversion[], SysMessage[];
  26. extern char *Callserver;
  27. extern short SecureTelnet;
  28. #ifdef RMAIL
  29. static void rmailit (FILE *fp,char *from, char *to, char *subject,long startat);
  30. #endif
  31. #if defined(REQSVR) || defined(RMAIL) || defined(MAILFILTER)
  32. static int handleError (FILE *fp,char *from, char *str);
  33. #endif
  34. #if defined(REQSVR) || defined(RMAIL) || defined(DELEGATE) || defined(MAILFILTER)
  35. static void getfield (char *into, char *from, int fieldtype);
  36. #endif
  37. static void rdaemon_str (char *str,const char *replyto, const char *from, const char *to, const char *msg, const char msgtype, int mode);
  38.  
  39. char *reqsvr_filter_subject = NULLCHAR;
  40. int reqsvr_bypass_permissions = 0;
  41.  
  42. static char DAEMONSTR[] = "%sREQSVR@%s (Mail Delivery Subsystem)\n";
  43.  
  44. static void
  45. rdaemon_str(str, replyto, from, to, msg, msgtype, mode)
  46. char *str;
  47. const char *replyto;
  48. const char *from, *to;
  49. const char *msg, msgtype;
  50. int mode;
  51. {
  52. FILE *fp;
  53.  
  54.     fp = tmpfile();
  55.     if (fp)    {
  56.         fputs (str, fp);
  57.         rewind (fp);
  58.         (void) rdaemon (fp, replyto, from, to, msg, msgtype, mode);
  59.         (void) fclose (fp);
  60.     }
  61. }
  62.  
  63.  
  64. int
  65. rdaemon(data, replyto, from, to, msg, msgtype, mode)
  66. FILE *data;        /* pointer to rewound data file */
  67. const char *replyto;
  68. const char *from, *to;
  69. const char *msg, msgtype;
  70. int mode;
  71. {
  72. time_t t;
  73. FILE *tfile;
  74. char buf[LINELEN], *newaddr, *orgto;
  75. long mid;
  76.  
  77.     if((tfile = tmpfile()) == NULLFILE)
  78.         return -1;
  79. /*    if (to == NULLCHAR)
  80.         mode = 1;        */
  81.     to = strdup ((to == NULLCHAR) ? "sysop" : to);
  82.         
  83.     orgto = strdup (to);
  84.     if((newaddr = rewrite_address(to, 0)) != NULLCHAR)    {
  85.         free (to);
  86.         to = newaddr;
  87.     }
  88.     (void) time(&t);
  89.     fprintf(tfile,Hdrs[RECEIVED]);
  90.     fprintf(tfile,"from %s ",Hostname);
  91.     mid = get_msgid(0);
  92. #ifdef MBFWD
  93.     fprintf(tfile,"by %s (%s) with SMTP\n\tid AA%ld ; %s",
  94.         Hostname, (Mbfwdinfo != NULLCHAR) ? Mbfwdinfo : shortversion, \
  95.         mid, ptime(&t));
  96. #else
  97.     fprintf(tfile,"by %s (%s) with SMTP\n\tid AA%ld ; %s",
  98.         Hostname, shortversion, mid, ptime(&t));
  99. #endif
  100.     fprintf(tfile,"%s%c\n",Hdrs[BBSTYPE], msgtype);
  101.     fprintf(tfile,"%s%s",Hdrs[DATE],ptime(&t));
  102.     mid = get_msgid(1);
  103.     fprintf(tfile,"%s<%ld@%s>\n",Hdrs[MSGID],mid,Hostname);
  104.     if (from == NULLCHAR)
  105.         fprintf(tfile,DAEMONSTR,Hdrs[FROM],Hostname);
  106.     else
  107.         fprintf(tfile,"%s%s\n",Hdrs[FROM],from);
  108.     fprintf(tfile,"%s%s\n",Hdrs[TO], strlwr(orgto));
  109.     if (replyto != NULLCHAR)
  110.         fprintf(tfile, "%s%s\n", Hdrs[REPLYTO], replyto);
  111.     fprintf(tfile,"%s%s\n\n",Hdrs[SUBJECT], msg);
  112.     kwait (NULL);
  113.     
  114.     if (data != NULLFILE)    {
  115.         if (mode)
  116.             fprintf(tfile,"  ===== Message %sfollows ====\n", (msg == SysMessage) ? "" : "header ");
  117.         while(fgets(buf,sizeof(buf),data) != NULLCHAR)    {
  118.             if(mode && buf[0] == '\n')
  119.                 break;
  120.             kwait (NULL);
  121.             fputs(buf,tfile);
  122.         }
  123. /*        if (mode && (msg != SysMessage))
  124.             fprintf(tfile,"  ===== Message Stored ====\n");        */
  125.     } else
  126.         fputc ('\n', tfile);
  127.     rewind(tfile);
  128.  
  129.     sprintf (buf, "REQSVR@%s", Hostname);
  130.     (void) mailuser(tfile, (from) ? from : buf, to, orgto);
  131.     free (to);
  132.     free (orgto);
  133.     (void) fclose(tfile);
  134.     kwait (NULL);
  135.     return 0;
  136. }
  137.  
  138. int
  139. dosendmail (argc,argv,p)
  140. int argc;
  141. char *argv[];
  142. void *p OPTIONAL;
  143. {
  144. FILE *fp;
  145. char *from, *to, *data, *subj;
  146. char buf[LINELEN];
  147.  
  148.     to = argv[1];
  149.     if (argc > 4) {
  150.         from = argv[2];
  151.         subj = argv[3];
  152.         data = argv[4];
  153.     } else {
  154.         sprintf (buf, "sysop@%s", Hostname);
  155.         from = buf;
  156.         subj = argv[2];
  157.         data = argv[3];
  158.     }
  159.     if (*data == '<')    {
  160.         /* filename given */
  161.         if ((fp = fopen (&data[1], "r")) == NULL) {
  162.             tprintf ("SendMail: Error opening file '%s'!", &data[1]);
  163.             return 0;
  164.         }
  165.         (void) rdaemon (fp, NULLCHAR, from, to, subj, 'P', 0);
  166.         (void) fclose (fp);
  167.     } else         /* string data given */
  168.         rdaemon_str (data, NULLCHAR, from, to, subj, 'P', 0);
  169.     smtptick (NULL);    /* wake SMTP to send that mail */
  170.     return 0;
  171. }
  172.  
  173.  
  174.  
  175. #if defined(REQSVR) || defined(RMAIL) || defined(DELEGATE) || defined(MAILFILTER) || defined(WPAGES) || defined(TUTOR)
  176.  
  177.  
  178. static void
  179. getfield (into, from, fieldtype)
  180. char *into, *from;
  181. int fieldtype;
  182. {
  183. char *cp, *temp;
  184.  
  185.     cp = &from[strlen(Hdrs[fieldtype])];
  186.     if (*cp == '"')    {
  187.         cp++;
  188.         if ((temp = strchr (cp, '"')) != NULLCHAR)
  189.             cp = temp+1;
  190.     }
  191.     if ((temp = strchr (cp, '<')) != NULLCHAR)    {
  192.         cp = temp+1;
  193.         if ((temp = strchr (cp, '>')) != NULLCHAR)
  194.             *temp = 0;
  195.     }
  196.     if ((temp = strpbrk (cp, " \t")) != NULLCHAR)
  197.         *temp = 0;
  198.     strcpy (into, cp);
  199. }
  200.  
  201.  
  202. void
  203. parseheader (fp, from, subject, to, bid, buf, startat)
  204. FILE *fp;
  205. char *from, *subject, *to, *bid, *buf;
  206. long *startat;
  207. {
  208. char *cp, *temp;
  209. int fieldtype;
  210.  
  211.     rewind (fp);
  212.     subject[0] = from[0] = 0;
  213.     while(fgets(buf,128,fp) != NULLCHAR)    {
  214.         if(buf[0] == '\n')
  215.             break;
  216.         rip (buf);
  217.         fieldtype = htype(buf);
  218.         if (fieldtype == FROM)    {
  219.             trimright (buf);
  220.             getfield (from, buf, fieldtype);
  221.         }
  222.         if (fieldtype == SUBJECT)    {
  223.             trimright (buf);
  224.             cp = &buf[strlen(Hdrs[SUBJECT])];
  225.             cp = skipwhite(cp);
  226.             if (*cp == '"')    {
  227.                 cp++;
  228.                 if ((temp = strchr (cp, '"')) != NULLCHAR)
  229.                     *temp = 0;
  230.             }
  231.             strcpy (subject, cp);
  232.         }
  233.         if ((to != NULLCHAR) && (fieldtype == TO))    {
  234.             trimright (buf);
  235.             getfield (to, buf, fieldtype);
  236.         }
  237.         if ((bid != NULLCHAR) && (fieldtype == MSGID))    {
  238.             trimright (buf);
  239.             getfield (bid, buf, fieldtype);
  240.         }
  241.     }
  242.     *startat = ftell (fp);
  243.     if (fgets(buf,128,fp) != NULLCHAR)    {
  244.         if(!strnicmp (buf, "R:", 2))    {
  245.             while(fgets(buf,128,fp) != NULLCHAR)    {
  246.                 if(buf[0] == '\n')
  247.                     break;
  248.             }
  249.             *startat = ftell (fp);
  250.         }
  251.     }
  252.     kwait (NULL);
  253. }
  254. #endif
  255.  
  256.  
  257.  
  258. #if defined(REQSVR) || defined(RMAIL) || defined(MAILFILTER)
  259.  
  260. static int
  261. handleError (fp, from, str)
  262. FILE *fp;
  263. char *from, *str;
  264. {
  265.     rewind (fp);
  266.     (void) rdaemon (fp, NULLCHAR, NULLCHAR, from, str, 'P', 1);
  267.     rewind (fp);
  268.     (void) rdaemon (fp, NULLCHAR, NULLCHAR, NULLCHAR, str, 'P', 1);
  269.     return 0;    /* pass the message back */
  270. }
  271.  
  272.  
  273. #endif
  274.  
  275.  
  276. #ifdef RMAIL
  277. static char rmailerror[] = "Rmail Error";
  278.  
  279. static void
  280. rmailit (fp, from, to, subject, startat)
  281. FILE *fp;
  282. char *from, *to, *subject;
  283. long startat;
  284. {
  285. char *thisto;
  286.  
  287.     while (to && *to)    {
  288.         thisto = to;
  289.         to = strchr (to, ',');
  290.         if (to)    {
  291.             *to++ = 0;
  292.             to = skipwhite (to);
  293.         }
  294.         if (!strnicmp (thisto, "rmail@", 6))
  295.             continue;
  296.         kwait (NULL);
  297.         fseek (fp, startat, SEEK_SET);
  298.         (void) rdaemon (fp, NULLCHAR, from, thisto, subject, 'P', 0);
  299.     }
  300. }
  301.  
  302.  
  303. int
  304. rmail (fp, from)
  305. FILE *fp;
  306. const char *from OPTIONAL;
  307. {
  308. char buf[512], subject[256], realfrom[128], *to = NULLCHAR;
  309. long startat;
  310.  
  311.     parseheader (fp, realfrom, subject, NULLCHAR, NULLCHAR, buf, &startat);
  312.     if (realfrom[0] && subject[0])        {
  313.         fseek (fp, startat, 0);
  314.         while(fgets(buf,512,fp) != NULLCHAR)    {
  315.             if(buf[0] == '\n')
  316.                 break;
  317.             if (htype(buf) == TO)    {
  318.                 if (to != NULLCHAR)    {    /* more than 1 To: - ERROR */
  319.                     free (to);
  320.                     to = NULLCHAR;
  321.                     break;
  322.                 } else    {
  323.                     rip(buf);
  324.                     to = strdup (&buf[4]);
  325.                 }
  326.             }
  327.         }
  328.         if (to != NULLCHAR)    {
  329.             rmailit (fp, realfrom, to, subject, startat);
  330.             free (to);
  331.             return 1;
  332.         }
  333.     }
  334.     return (handleError (fp, realfrom, rmailerror));
  335. }
  336.  
  337. #endif
  338.  
  339.  
  340.  
  341. #if defined(REQSVR) || defined(MAILFILTER)
  342. int
  343. reqsvr (fp, from)
  344. FILE *fp;
  345. const char *from OPTIONAL;
  346. {
  347. char buf[128], smallbuf[2];
  348. char name[128], path[128], realfrom[128];
  349. char subject[LINELEN], *file, cmd, *cp = path, action = 'I', *ptr, *ptr2;
  350. char *ptr3, *cp1, *cp2;
  351. int anony = 1, mode = RETR_CMD, found = 0 /*, first = 0*/ ;
  352. FILE *out, *out2;
  353. long prev, msgdata, privs;
  354. unsigned attr = 0;
  355. int overrideperm = 0;
  356. #ifdef SAMCALLB
  357. int err;
  358. #endif
  359. #if defined(SAMCALLB) || defined(CALLCLI)
  360. struct mbx *mb;
  361. #endif
  362.  
  363.     parseheader (fp, realfrom, subject, NULLCHAR, NULLCHAR, buf, &prev);
  364.     if (reqsvr_filter_subject)    {
  365.         strcpy (subject, reqsvr_filter_subject);
  366.         reqsvr_filter_subject = NULLCHAR;
  367.     }
  368.     if (reqsvr_bypass_permissions)    {
  369.         overrideperm = 1;
  370.         reqsvr_bypass_permissions = 0;
  371.     }
  372.     sprintf(buf,"%s/reqsvr.log", LOGdir);
  373.     if((out = fopen(buf,APPEND_TEXT)) != NULLFILE)    {
  374.         time_t t;
  375.         (void) time(&t);
  376.         fprintf (out, "Received from %s (%s) on %s", realfrom, subject, ptime(&t));
  377.         (void) fclose (out);
  378.     }
  379.     if (!*subject)
  380.         return 0;    /* we are konfuzd! No subject!?!? */
  381.     kwait (NULL);
  382.  
  383. #if 0
  384.     /*
  385.     ** This code to detect R: headers is a problem.
  386.     ** parseheader() already seeks past R: Headers 
  387.     ** so the first line seen here is a blank line.
  388.     ** This causes any non blank lines to be skipped
  389.     ** until another blank line is encountered.
  390.     ** (sometimes the entire message !) -- N0EIR
  391.     */
  392.     do    {
  393.         if (fgets(buf,128,fp) == NULLCHAR)
  394.             break;
  395.         if (!first && *buf == '\n')
  396.             strcpy (buf, "R:");
  397.         if (!strnicmp (buf, "R:", 2))
  398.             found = 1;
  399.         first = 1;
  400.     } while (*buf != '\n');
  401.     if (!found)
  402.         fseek (fp, prev, SEEK_SET);
  403. #endif
  404.  
  405. /*    else
  406.         fgets(buf,128,fp);    */    /* strip off blank line */
  407.  
  408.     /* now the fix for FBB/PRMBS/TNOS adding RFC 822-type lines to messages */
  409.     prev = ftell (fp);
  410.     if (fgets (buf, 128, fp) != NULLCHAR)    {
  411.         if (strnicmp (buf, "From:", 5) && strnicmp (buf, "Date:", 5) && strnicmp (buf, "Message-Id:", 11))
  412.             fseek (fp, prev, SEEK_SET);
  413.         else    do    {
  414.                 if (fgets (buf, 128,fp) == NULLCHAR)
  415.                     break;
  416.             } while (*buf != '\n');
  417.     }
  418.  
  419.     msgdata = ftell (fp);
  420.     strncpy (name, realfrom, 40);
  421.     file = strchr (name, '@');
  422.     if (file)
  423.         *file = 0;
  424.     cmd = (char) tolower (*subject);
  425.     /* get senders permissions and default path */
  426.     privs = userlogin (name, NULLCHAR, &cp, 128, &anony);
  427.     
  428.     file = skipnonwhite (&subject[1]);
  429.     file = skipwhite (file);
  430.     cp1 = strdup(cp);
  431.     if ((cp2 = strchr(cp1, ';')) != NULLCHAR)
  432.         *cp2 = '\0';
  433.     file = pathname (cp1, file);
  434.     free (cp1);
  435. #ifdef DOS_GETFILEATTR
  436.     (void) _dos_getfileattr (file, &attr);
  437. #endif
  438.     if (!strnicmp (subject, "infor", 5))
  439.         cmd = 'f';    /* inform */
  440.     if (!strnicmp (subject, "uni", 3))
  441.         cmd = 'n';    /* uninform */
  442.     if (!strnicmp (subject, "uns", 3))
  443.         cmd = 'c';    /* unsubscribe */
  444.  
  445.     switch (cmd)    {
  446.         case 'i':    /* info */
  447.         case 'h':    /* help */
  448.                 free (file);
  449.                 file = pathname (Helpdir, "reqsvr.hlp");
  450.                 if ((out = fopen (file, READ_TEXT)) != NULLFILE)
  451.                     goto okay;
  452.                 sprintf (buf, "Not Found %s", subject);
  453.                 goto error;
  454.         case 'g':    /* group commands */
  455.                 ptr = skipnonwhite (&subject[1]);
  456.                 ptr = skipwhite (ptr);
  457.                 cmd = (char) tolower (*ptr);
  458.                 if (cmd != 's' && cmd != 'u' && cmd != 'l')
  459.                     if (privs == -1 || !(privs & SYSOP_CMD))
  460.                         goto denied;
  461.  
  462.                 ptr2 = skipnonwhite (ptr);
  463.                 action = *ptr2;
  464.                 *ptr2++ = 0;
  465.                 ptr2 = skipwhite (ptr2);
  466.                 ptr3 = strdup (ptr2);
  467.                 ptr3 = strcat (ptr3, ".hlp");
  468.                 switch (cmd)    {
  469.                     case 's':
  470.                     case 'u':
  471.                     case 'a':
  472.                     case 'd':
  473.                     case 'i':
  474.                     case 'l':    out = NULLFILE;
  475.                             found = groupcommand (ptr, (action) ? ptr2 : NULLCHAR, realfrom, 0, &out, fp);
  476.                             *(--ptr2) = action;
  477.                             if (found)    {
  478.                                 if (cmd == 's')    {
  479.                                     file = pathname (Helpdir, ptr3);
  480.                                     if ((out = fopen (file, READ_TEXT)) != NULLFILE)
  481.                                         goto okay;
  482.                                 }
  483.                                 if (cmd == 'l')
  484.                                     goto done;
  485.                                 else 
  486.                                     goto okay;
  487.                             } else
  488.                                 goto denied;
  489.                     default:    *(--ptr2) = action;
  490.                             goto confuzed;
  491.                 }
  492.         case 'q':    /* return callbook server data */
  493. #if defined(SAMCALLB) || defined(CALLCLI)
  494.                 ptr = skipnonwhite (&subject[1]);
  495.                 ptr = skipwhite (ptr);
  496.                 if((out = tmpfile()) != NULLFILE){
  497. #ifdef SAMCALLB
  498.                     if ((err = cb_lookup (0, ptr, out)) != 0)    {
  499.                         if (err == 1)    {
  500. #endif
  501.                             if (Callserver && *Callserver)    {
  502.                                 char *newargv[3], bufport[8], cmdbuf[4];
  503.  
  504.                                 mb = (struct mbx *)callocw(1,sizeof(struct mbx));
  505.                                 mb->quickfile = out;
  506.                                 strcpy (cmdbuf, "C");
  507.                                 newargv[0] = cmdbuf;
  508.                                 newargv[1] = Callserver;
  509.                                 sprintf(bufport,"%d",IPPORT_CALLDB);
  510.                                 newargv[2] = bufport;
  511.                                 mb->startmsg = mallocw(80);  /* is freed each time by gw_connect() */
  512.                                 sprintf(mb->startmsg,"%s\n", ptr);
  513.                                 SecureTelnet = 0;
  514.                                 strcpy (mb->name, "reqsvr");
  515.                                 mb->stype = '+';
  516.                                 (void) dombtelnet(3,newargv,mb);
  517.                                 free (mb);
  518.                             } else
  519.                                 goto confuzed;
  520. #ifdef SAMCALLB
  521.                         } else
  522.                             fprintf (out, "Amateur callsign '%s' not found or invalid\n", ptr);
  523.                     }
  524. #endif
  525.                     goto okay;
  526.                 }
  527. #endif
  528.                 goto ioerror;
  529.         case 'v':    /* return version info */
  530.                 if((out = tmpfile()) != NULLFILE){
  531.                     fprintf (out, "Currently running %s at %s\n", Version, Hostname);
  532.                     goto okay;
  533.                 }
  534.                 goto ioerror;
  535.         case 'u':    /* upload a file */
  536.                 mode = STOR_CMD;    /*lint !e616 */
  537.         case 's':    /* subscribe to a file */
  538.         case 'c':    /* unsubscribe to a file */
  539.         case 'f':    /* inform of changes to a file */
  540.         case 'n':    /* uninform of changes to a file */
  541.         case 'w':    /* send a directory */
  542.         case 'd':    /* download a file */
  543.                 if ((!overrideperm && privs == -1) || !permcheck(path, privs, mode, file))    {
  544. denied:                    sprintf (buf, "Denied %s", subject);
  545.                     goto error;
  546.                 }
  547.                 switch (cmd)    {
  548.                     case 'c':    /* unsubscribe */
  549.                     case 'n':    /* uninform */
  550.                     case 's':    /* subscribe */
  551.                     case 'f':    /* inform */
  552.                         if (cmd == 'c' || cmd == 's')    /* subscribe functions */
  553.                             action = 'S';
  554.                         if(attr & FA_DIREC)    { /* whole dir */
  555.                             smallbuf[0] = '/';
  556.                             smallbuf[1] = 0;
  557.                             cp = smallbuf;
  558.                         } else    {
  559.                             cp = strrchr (file, '/');
  560.                             if (cp)
  561.                                 *cp++ = 0;
  562.                         }
  563.                         sprintf(buf,"%s/reqsvr.dat",file);
  564.                         if (cmd == 's' || cmd == 'f')    {    /* adding functions */
  565.                             if((out = fopen(buf,APPEND_TEXT)) != NULLFILE)    {
  566.                                 fprintf (out, "%s %s %c\n", cp, realfrom, action);
  567.                                 goto complete;
  568.                             }
  569.                             goto ioerror;
  570.                         } else    {        /* removing functions */
  571.                             if((out = fopen(buf,UPDATE_TEXT)) != NULLFILE)    {
  572.                                 while(fgets(buf,128,out) != NULLCHAR)    {
  573.                                     char *tmp1;
  574.                                     kwait (NULL);
  575.                                     rip (buf);
  576.                                     if (cp && !strnicmp (buf, cp, strlen (cp)))    {
  577.                                         tmp1 = strchr (buf, ' ');
  578.                                         if (tmp1)
  579.                                             if (!strnicmp (++tmp1, realfrom, strlen (realfrom)))
  580.                                                 if (buf[strlen(buf) - 1] == action)    {
  581.                                                     fseek (out, (long) (ftell (out) - 3), SEEK_SET);
  582.                                                     fputc ('N', out);
  583.                                                     break;
  584.                                                 }
  585.                                     }
  586.                                 }
  587.                             }
  588.                             goto complete;
  589.                         }
  590.                     case 'w':    /* what (dir) */
  591.                         if((out = dir(file, 1)) == NULLFILE)
  592.                             goto ioerror;
  593.                         goto okay;
  594.                     case 'u':    /* upload */
  595.                         if ((out = fopen (file, WRITE_TEXT)) == NULLFILE)    {
  596. ioerror:                        sprintf (buf, "IO Error %s", subject);
  597.                             goto error;
  598.                         }
  599.                         while(fgets(buf,128,fp) != NULLCHAR)    {
  600.                             kwait (NULL);
  601.                             fputs(buf,out);
  602.                         }
  603.                         (void) fclose (out);
  604.                         cp = strrchr (file, '/');
  605.                         if (cp)
  606.                             *cp++ = 0;
  607.                         sprintf(buf,"%s/reqsvr.dat",file);
  608.                         if((out = fopen(buf,READ_TEXT)) != NULLFILE)    {
  609.                             if((out2 = tmpfile()) != NULLFILE)
  610.                                 fprintf (out2, "File changed by %s\n", realfrom);
  611.                             while(fgets(name,128,out) != NULLCHAR)    {
  612.                                 kwait (NULL);
  613.                                 if (!cp)
  614.                                     goto confuzed;
  615.                                 if (*name == '/' || !strnicmp (name, cp, strlen (cp)))    {
  616.                                     ptr = strrchr (name, ' ');
  617.                                     if (!ptr)
  618.                                         goto confuzed;
  619.                                     *ptr = 0;
  620.                                     action = ptr[1];
  621.                                     ptr = strchr (name, ' ');
  622.                                     if (!ptr)
  623.                                         goto confuzed;
  624.                                     ptr++;
  625.                                     switch (action)    {
  626.                                          case 'S':
  627.                                              sprintf (buf, "Subscribe %s/%s", file, cp);
  628.                                              fseek (fp, msgdata, SEEK_SET);
  629.                                              (void) rdaemon (fp, NULLCHAR, NULLCHAR, ptr, buf, 'P', 0);
  630.                                              break;
  631.                                          case 'I':
  632.                                              sprintf (buf, "Inform %s/%s", file, cp);
  633.                                             if (out2 != NULLFILE)
  634.                                                 rewind (out2);
  635.                                              (void) rdaemon (out2, NULLCHAR, NULLCHAR, ptr, buf, 'P', 0);
  636.                                              break;
  637.                                          default:
  638.                                              break;
  639.                                     }
  640.                                 }
  641.                             }
  642.                             if (out2 != NULLFILE)
  643.                                 (void) fclose (out2);
  644.                         }
  645. complete:                    if (out != NULLFILE)    {
  646.                             (void) fclose (out);
  647.                             out = NULLFILE;
  648.                         }
  649.                         if (!strnicmp (subject, "uploadblind", 11) || !strnicmp (subject, "ub", 2))
  650.                             goto done;
  651.                         goto okay;
  652.                     case 'd':    /* download */
  653.                         if ((out = fopen (file, READ_TEXT)) == NULLFILE)
  654.                             goto ioerror;
  655. okay:                        sprintf (buf, "Accepted %s", subject);
  656.                         if (out != NULLFILE)
  657.                             rewind (out);
  658.                         (void) rdaemon (out, NULLCHAR, NULLCHAR, realfrom, buf, 'P', 0);
  659.                         if (out != NULLFILE)
  660.                             (void) fclose (out);
  661.                         break;
  662.                     default:
  663.                         break;
  664.                 }
  665.                 break;
  666. confuzed:
  667.         default:    sprintf (buf, "Unknown %s", subject);    /*lint !e616 */
  668.                 goto error;
  669.     }
  670. done:    free (file);
  671.     return 1;    /* we handled it, here! */
  672.  
  673. error:    free (file);
  674.     return (handleError (fp, realfrom, buf));
  675. }
  676.  
  677. #endif
  678.